/** Project 3
 *
 * @Group Members
 * 	Brentton Garber - mrbrentgarber@gmail.com
 * 	Georgii Tkachuk - georgii.t@gmail.com
 * 	Lucas Bridge - ltbridge@asu.edu
 * 	Austin Burnham - burnhamaustin@gmail.com
 * 	Kevin Greenberg - kgreenbe@asu.edu
 * @Revision
 *
 * @Since
 *
 */

#include <iostream>
#include "Scanner.h"




Scanner::Scanner(const string &filename)
{
	// initialize the sourceLineIndex to zero
	sourceLineIndex = 0;
	sourceLine = "";

	// create a new instance of the printer class
	printer = new Print(filename);

	// open the file specified
	sourceFile = fopen(filename.c_str(), "r");

	// check if the file is open. if it is not, tell us that we failed.
	if(sourceFile == NULL)
		cout << "COULD NOT FIND FILE!" <<endl;

	char ch;
	int i;
    for(i = 0; i < 128; i++)
	{       
                charTable[i] = SPECIAL;
	}
	for(ch = '0'; ch <= '9'; ch++)
	{
		charTable[ch] = DIGIT;
	}
	for(ch = 'a'; ch <= 'z'; ch++)
	{
		charTable[ch] = LETTER;
	}
	for(ch = 'A'; ch <= 'Z'; ch++)
	{
		charTable[ch] = LETTER;
	}
       
}

Scanner::~Scanner()
{
	// when the class is being destroyed, close the current file if it is open.
	if(sourceFile != NULL)
		fclose(sourceFile);
}

void Scanner::ScanFile(Tokenizer &tokenizer)
{
//    do
//    {
//        printer->PrintLine(sourceLine);
//        if (GetCharacter() == '\0')
//        {
//            BackUpCharacter();
//            if(GetSourceLine() == true)
//                sourceLineIndex =0;
//            
    
    while(true)
	{
		char ch = GetCharacter();
        if(ch != '\0' && ch != '\n' && ch != '\r')
        {
            BackUpCharacter();
            tokenizer.GetToken(charTable);
            printer->PrintToken(tokenizer);
        }
        else 
        {
            if(!GetSourceLine()) break;
            printer->PrintLine(sourceLine);
            sourceLineIndex = 0;
        }
    }
//    }while(tokenizer.GetTokenCode() != 36);	// needs to be worked on.
}
//new method that will return the type of the current character 
CharCode Scanner::GetCharType(char &tokChar)
{
    return charTable[tokChar];
}

bool Scanner::GetSourceLine()
{
	// create our source buffer
	char source_buffer[MAX_SOURCE_LINE_LENGTH];
	
	// try and read from the file. Return false if we failed.
	if(fgets(source_buffer, MAX_SOURCE_LINE_LENGTH,sourceFile) == NULL) return false;

	// store the line in the private class variable 'sourceLine'
	sourceLine = source_buffer;

	// return true, since we found a new line
	return true;
}

void Scanner::SkipComment()             //this should be called when the current character is '{'
{   
    while (sourceLine[sourceLineIndex] != '}')
    {
        if(sourceLineIndex == sourceLine.length() || sourceLine.length() == 0)
        {
             if(GetSourceLine() == true)
            sourceLineIndex = 0;
        }
        else 
            sourceLineIndex++;
       
    }
}

void Scanner::BackUpCharacter()
{       
        
//// if the source line is above 0, decrease the current index. aka backup from the current character.
	if(sourceLineIndex > 0) 
		sourceLineIndex--;
}

char Scanner::GetCharacter()
{
    	// if the source file is not open, return null
	if(sourceFile == NULL) return NULL;
        // if the source line index is less then the length of the sourceline-1, then increase the sourceLine index
//	while(sourceLineIndex == (int)sourceLine.length() - 1 || sourceLine.length() == 0)
//        //else, get the next source line and reset the index to 0
//	{
//            cout<< "1.5" << endl;
//            if(GetSourceLine() == true)
//		sourceLineIndex = 0;
//        }
//	
	//else return '\0';
        if(sourceLineIndex == sourceLine.length() || sourceLine.length() == 0)
        {
            sourceLineIndex = 0;
            return '\0';
        }
        
        //if current character is the beginning of a comment, skip comment
        //if (sourceLine[sourceLineIndex] == '{')
        //    SkipComment();
        sourceLineIndex++;
        // if the code gets this far, return the source line character.
	return sourceLine[sourceLineIndex-1];
}



